﻿#pragma once

#include "Misc/EngineEditorMacros.h"
#include "Framework/EditorModelSubsystem.h"
#include "ProjectInfo.h" 
#include "Containers/ScriptDelegateImplement.h"
#include "Asset/AssetPackage.h"
#include "Framework/SubsystemManager.h"
#include "ProjectModel.m.h"

RCLASS()
class RProjectModel : public REditorModelSubsystem    
{
    ROBJECT

public:
    static RProjectModel* Get();
    virtual void Initialize() override;
    virtual void Deinitialize() override;    

    virtual void FirstTimeInitializeObject();

    //在指定路径创建一个新的项目
    //@ProjectPath, a empty folder path
    //return error message if failed
    TOptional<CString> CreateProject(const CString& ProjectName, const SPath& ProjectPath);
    
    //open a exist project folder
    TOptional<CString> OpenProject(const SPath& ProjectFolderPath);

    RFIELD()
    TScriptDelegate<void()>  OnProjectOpened;

    RFIELD()
    TScriptDelegate<void()>  OnProjectClosed;

    bool IsProjectOpened() const { return CurrentProjectInfo.HasValue(); }

    TOptional<SProjectPathInfo> GetCurrentProjectInfo() const { return CurrentProjectInfo; }

    TOptional<SPath> GetProjectDirectory() const;

    TOptional<SPath> GetAssetDirectory() const;

    TOptional<SAssetPackage> GetAssetPackage() const;

    static CString GetProjectExtension()  { return U".Wuhua"; }


protected:
    TOptional<SProjectPathInfo> CurrentProjectInfo;

public:
    //build the project
    //return error message if failed
    TOptional<CString> BuildProject();

    //launch the project
    //return false if failed
    // bool LaunchProject(
    //     bool bDebugMode
    //     ,uint32_t DebugPort    
    // );

    //创建启动工程的命令
    CString CreateLaunchCommand(
        bool bDebugMode
        ,uint32_t DebugPort
    );

protected:
    template<typename SubsystemType>
    TSharedObjectPtr<SubsystemType> GetSubsystem()
    {
        return SubsystemManager->GetSubsystem<SubsystemType>();
    }
protected:
    RFIELD()
    TSharedObjectPtr<RSubsystemManager> SubsystemManager;
    

};